package jp.sourceforge.akjrcp.dropsomething;


import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jp.sourceforge.akjrcp.akj_betas.Akj_betasPlugin;
import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.dropsomething.FFMpegConvertTabBuilder.FFMpegConvertTab;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegExecuter;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegFLVParser;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegOptions;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegPreference;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUI;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUtils;
import jp.sourceforge.akjrcp.ffmpeg.FLVInfomation;
import jp.sourceforge.akjrcp.flvtools.explorer.ThumbnailManager;
import jp.sourceforge.akjrcp.psp.PSPFFMpegPreference;
import jp.sourceforge.akjrcp.psp.PSPMovieSetting;
import jp.sourceforge.akjrcp.ui.DirectryBasedExecuterListener;
import jp.sourceforge.akjrcp.ui.FileOverwriteControler;
import jp.sourceforge.akjrcp.ui.GenericParameters;
import jp.sourceforge.akjrcp.ui.GenericParametersFieldEditor;
import jp.sourceforge.akjrcp.ui.GenericParametersFFMpegPreference;
import jp.sourceforge.akjrcp.ui.GenericParametersSaveDialog;
import jp.sourceforge.akjrcp.ui.GenericParametersTableViewer;
import jp.sourceforge.akjrcp.ui.param.ParamBoolean;
import jp.sourceforge.akjrcp.ui.param.ParamCheckGroup;
import jp.sourceforge.akjrcp.ui.param.ParamCombo;
import jp.sourceforge.akjrcp.ui.param.ParamItem;
import jp.sourceforge.akjrcp.ui.param.ParamItemActionListener;
import jp.sourceforge.akjrcp.ui.param.ParamText;
import jp.sourceforge.akjrcp.util.FileNameUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;

/**
 * @deprecated finished
 * @author aki
 *
 */
public class H264ConvertTabBuilder implements IDropSomething{
	public static Log log=LogFactory.getLog(H264ConvertTabBuilder.class);
	private FileOverwriteControler fileOverwriteControler;
	
	public static final String TYPE_SELECT="type_select";
	
	public static final String AVISYNTH="avisynth";
	
	public static final String H264CONVERT="h264convert";
	
	
	private DropsomethingTab dtab;
	private CTabItem tabItem1 ;
	
	public void createControl(final ViewPart part,final CTabFolder tab) {
		if(dtab==null){
			//deley create control
			dtab=new H264ConvertTab(tab,SWT.NULL);
			dtab.setViewPart(part);
			tabItem1.setControl(dtab);
		}
	}
	public void createTab(ViewPart part, CTabFolder tab) {
		 tabItem1 = new CTabItem(tab, SWT.NONE);
		tabItem1.setText(Messages.getString("h264convert.tab"));
		
		
	
		
		
		fileOverwriteControler=new FileOverwriteControler(tab.getShell());
	}
	
	public class H264ConvertTab extends DirectoryBasedDropSomething{

		private FFMpegExecuter ffmpegExecuter;

		private Label dragHere;

		

		private String currentTarget;
		
		//private List buttonList;
		
		private Button avisynth;
	//	private Button twoPass;
		
		public H264ConvertTab(Composite parent, int style) {
			super(parent, style);
			
			
		}

		private List settingList;

		private GenericParametersTableViewer tableViewer;
		private List<ParamItem> paramList;

		private Button saveSetting;
		
		ItemModifyCheck itemModifyCheck;
		public void addParamList(ParamItem item){
			paramList.add(item);
			item.setParamItemActionListener(itemModifyCheck);
		}
		
		public class ItemModifyCheck implements ParamItemActionListener{

			public void paramItemModified(ParamItem source) {
				boolean modified=false;
				for (int i = 0; i < paramList.size(); i++) {
					ParamItem item=paramList.get(i);
					if(item.isModified()){
						//log.info("modified:"+item.getKey());
						modified=true;
						break;
					}
					
				}
				//log.info("enabled:"+modified);
				saveSetting.setEnabled(modified);
			}
			
		}
		public class SelectChanged implements ISelectionChangedListener{

			public void selectionChanged(SelectionChangedEvent event) {
				tableSelectionChanged();
			}
			
		}
		
		public Map toNewParameterMap(){
			Map parameterMap=new HashMap();
			for (int i = 0; i < paramList.size(); i++) {
				ParamItem item=paramList.get(i);
				if(item.getValue().length()>0){
					parameterMap.put(item.getKey(), item.getValue());
				}
			}
			return parameterMap;
		}
		
		public void tableSelectionChanged(){
			saveSetting.setEnabled(false);//changed
			int selection=tableViewer.getTable().getSelectionIndex();
			if(selection>=0){
			log.info("table item changed:"+selection);
			GenericParameters parameters=(GenericParameters) tableViewer.getTable().getItem(tableViewer.getTable().getSelectionIndex()).getData();
			log.info("size:"+paramList.size());
			Map map=parameters.getParameters();
			for (int i = 0; i < paramList.size(); i++) {
				ParamItem item=paramList.get(i);
				String value=(String) map.get(item.getKey());
				if(value!=null){
					log.info(item.getKey()+","+value);
					item.setValue(value);
				}else{
					item.setValue("");
				}
			}
		}
		}
		
		public class GenericSave implements SelectionListener {

			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				GenericParameters parameter=tableViewer.getCurrentSelection();
				String newName=tableViewer.copiedName(parameter);
				GenericParametersSaveDialog dialog=new GenericParametersSaveDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
				
				dialog.setName(newName);
				dialog.setComment(parameter.getComment());
				int ret=dialog.open();
				if(ret==Dialog.OK){
					log.info("Save:"+dialog.isSaveOverwrite());
					Map newMap=toNewParameterMap();
					if(dialog.isSaveOverwrite()){
//						overwrite or copy
						parameter.setParameters(newMap);
						parameter.setComment(dialog.getComment());
					}else{
						GenericParameters newParam=new GenericParameters(newMap);
						newParam.setName(dialog.getName());
						newParam.setComment(dialog.getComment());
						
						tableViewer.getGenericParameters().add(newParam);
						tableViewer.refresh();//
					}
					//store data
					int selection=tableViewer.getTable().getSelectionIndex();
					GenericParameters infos[] = (GenericParameters[]) tableViewer.getGenericParameters().toArray(new GenericParameters[0]);
					//String oldValue=getPreferenceStore().getString(H264SettingPage.EXPORT_H264_SETTINGS);
					String newValue=GenericParametersFieldEditor.toStoreString(infos);
					//set only difference
					
					getPreferenceStore().setValue(H264SettingPage.EXPORT_H264_SETTINGS,newValue);
					
					//save store
					//maybe selection change ,what should i do.remember and reselect.
					tableViewer.getTable().setSelection(selection);
					tableSelectionChanged();
					//update value;
				}
			}

		}

		public Composite createControls(Composite parent) {
			itemModifyCheck=new ItemModifyCheck();
			
			paramList=new ArrayList<ParamItem>();
			Composite composite=new Composite(parent,SWT.NULL);
			composite.setLayout(new GridLayout(1,true));
			
			Composite listComposite=new Composite(composite,SWT.NULL);
			listComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			listComposite.setLayout(new GridLayout(2,false));
			
			List list=GenericParametersTableViewer.loadList(getPreferenceStore().getString(H264SettingPage.EXPORT_H264_SETTINGS));
			
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			//gd.minimumHeight=40;
			gd.heightHint=40;
			//gd.grabExcessVerticalSpace=true;
			tableViewer = new GenericParametersTableViewer(listComposite);
			tableViewer.getTable().setLayoutData(gd);
			tableViewer.setGenericParametersList(list);
			
			tableViewer.addSelectionChangedListener(new SelectChanged());
			
			
			saveSetting = new Button(listComposite,SWT.NULL);
			saveSetting.setText(Messages.getString("h264converter.save"));
			saveSetting.setEnabled(false);
			saveSetting.addSelectionListener(new GenericSave());
			
			//buttonList=new ArrayList();
			settingList=new ArrayList();
			setPreferenceKey(H264CONVERT);
			
			SavePreferenceStore savePreference=new SavePreferenceStore();//for save controls
			
			
			CTabFolder tab = new CTabFolder(composite, SWT.BOTTOM|SWT.FLAT);
			tab.setLayoutData(new GridData(GridData.FILL_BOTH));
			Composite basicComposite=new Composite(tab,SWT.NONE);
			basicComposite.setLayout(new GridLayout(1,true));
			CTabItem tabItem1 = new CTabItem(tab, SWT.NONE);
			tabItem1.setText("Basic");
			
			tabItem1.setControl(basicComposite);
			
			createDirectoryInfo(basicComposite);
			/*
			twoPass = new Button(composite, SWT.CHECK);
			twoPass.setText(Messages.getString("mpegconvert.twopass"));
			//twoPass.setSelection(getPreferenceStore().getBoolean(PREFERENCE_TWO_PASS));
			twoPass.setToolTipText(Messages
					.getString("mpegconvert.twopass_tooltip"));
			twoPass.addSelectionListener(savePreference);
			twoPass.setVisible(false);//now not support
			*/
			
			avisynth = new Button(basicComposite, SWT.CHECK);
			avisynth.setText(Messages.getString("pspconvert.use_avisynth"));
			//avisynth.setSelection(getPreferenceStore().getBoolean(PREFERENCE_AVISAYNTH));
			avisynth.setToolTipText(Messages
					.getString("pspconvert.use_avisynth_tooltip"));
			avisynth.addSelectionListener(savePreference);
			
			
			dragHere=new Label(basicComposite,SWT.NULL);
			dragHere.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			
			restoreControl(avisynth);
			
			Group formatGroup=new Group(basicComposite,SWT.NULL);
			formatGroup.setText("Format");
			formatGroup.setLayout(new GridLayout(2,true));
			ParamCombo extension= new ParamCombo(formatGroup,SWT.NONE,"EXTENSION","[Exteision]",
					new String[]{"mp4","3gp","3g2","mov","avi","m4v"});
			addParamList(extension);
			
			ParamCombo f= new ParamCombo(formatGroup,SWT.NONE,"f","Format(f)",
					new String[]{"mp4","3gp","3g2","psp","mov"});
			addParamList(f);
			
			
			
			Group vgroup=new Group(basicComposite,SWT.NULL);
			vgroup.setLayout(new GridLayout(6,false));
			vgroup.setText("Video");
			GridData vdata=new GridData();
			vdata.minimumHeight=120;
			vdata.grabExcessVerticalSpace=false;
			vgroup.setLayoutData(vdata);
			
			ParamCombo vcodec= new ParamCombo(vgroup,SWT.NONE,"vcodec","vcodec",
					new String[]{"h264","mpeg4","xvid"});
			addParamList(vcodec);
			
			ParamCombo r= new ParamCombo(vgroup,SWT.NONE,"r","rate",
					new String[]{"12","14.895","15","25","29.97","30","ntsc","pal","30000/1001"});
			addParamList(r);
			
			ParamCombo s= new ParamCombo(vgroup,SWT.NONE,"s","size",
					new String[]{"","176x144","176x144","208x176","416x352","208x208","320x240","640x480","720x480"});
//			"160x128","176x96","176x128","176x144","208x176"
			addParamList(s);
			
			ParamCombo b= new ParamCombo(vgroup,SWT.NONE,"b","bitrate(b)",
					new String[]{"384k","700k","768k","1536k","3072k"});
			addParamList(b);
			
			ParamCombo bt= new ParamCombo(vgroup,SWT.NONE,"bt","bt",
					new String[]{"384k","700k","768k","1536k","3072k"});
			addParamList(bt);
			
			ParamCombo bufsize= new ParamCombo(vgroup,SWT.NONE,"bufsize","bufsize",
					new String[]{"224k","384k","700k","768k","1536k","3072k","4096k"});
			addParamList(bufsize);
			
			ParamCombo maxrate= new ParamCombo(vgroup,SWT.NONE,"maxrate","maxrate",
					new String[]{"384k","768k","1000k","1536k","3072k","4000k","10000k"});
			addParamList(maxrate);
			
			ParamCombo vtag= new ParamCombo(vgroup,SWT.NONE,"vtag","vtag",
					new String[]{"XVID","mp4v","DX50"});
			addParamList(vtag);
			
			ParamCombo crf= new ParamCombo(vgroup,SWT.NONE,"crf","crf",
					new String[]{"15","20","26","32","34"});
			addParamList(crf);
			
			ParamCombo level= new ParamCombo(vgroup,SWT.NONE,"level","level",
					new String[]{"13","21","30"});
			addParamList(level);
			
			ParamCombo aspect= new ParamCombo(vgroup,SWT.NONE,"aspect","aspect",
					new String[]{"","4:3","16:9"});
			addParamList(aspect);
			
			ParamBoolean sameq= new ParamBoolean(vgroup,SWT.NONE,"sameq","sameq");
			addParamList(sameq);
			
			ParamBoolean vn= new ParamBoolean(vgroup,SWT.NONE,"vn","vn");
			addParamList(vn);
			
			ParamBoolean deinterlace= new ParamBoolean(vgroup,SWT.NONE,"deinterlace","deinterlace");
			addParamList(deinterlace);
			
			Group agroup=new Group(basicComposite,SWT.NULL);
			agroup.setText("Audio");
			agroup.setLayout(new GridLayout(6,false));
			GridData adata=new GridData();
			adata.minimumHeight=120;
			adata.grabExcessVerticalSpace=false;
			agroup.setLayoutData(adata);
			
			ParamCombo acodec= new ParamCombo(agroup,SWT.NONE,"acodec","acodec",
					new String[]{"aac","mp3"});
			addParamList(acodec);
			
			ParamCombo ab= new ParamCombo(agroup,SWT.NONE,"ab","ab",
					new String[]{"32k","64k","96k","128k","160k"});
			addParamList(ab);
			
			ParamCombo ar= new ParamCombo(agroup,SWT.NONE,"ar","ar",
					new String[]{"","8000","16000","22050","24000","32000","44100","48000"});
			addParamList(ar);
			
			ParamCombo ac= new ParamCombo(agroup,SWT.NONE,"ac","ac",
					new String[]{"","2","1"});
			addParamList(ac);
			
			ParamCombo vol= new ParamCombo(agroup,SWT.NONE,"vol","vol",
					new String[]{"","224","256","288","320","352","384"});
			addParamList(vol);
			
			ParamBoolean an= new ParamBoolean(agroup,SWT.NONE,"an","an");
			
			addParamList(an);
			
			
			
			Composite advancedComposite=new Composite(tab,SWT.NONE);
			advancedComposite.setLayout(new GridLayout(1,true));
			CTabItem tabItem2 = new CTabItem(tab, SWT.NONE);
			tabItem2.setText("Advanced");
			
			tabItem2.setControl(advancedComposite);
			
			
			ParamCheckGroup flags=new ParamCheckGroup(advancedComposite,SWT.NONE,"flags","flags",
					new String[]{"mv4","obmc","qpel","loop","gmc","mv0","part","gray","psnr","naq","ildct","low_delay",
					"alt","bitexact","aic","umv","cbp","qprd","aiv","slice","ilme","scan_offset","cgop"},12);
			addParamList(flags);
			String text="";
			text+="-flags             <flags> EDVA.\n";
			text+="   mv4                     E.V.. use four motion vector by macroblock (mpeg4)\n";
			text+="   obmc                    E.V.. use overlapped block motion compensation (h263+)\n";
			text+="   qpel                    E.V.. use 1/4 pel motion compensation\n";
			text+="   loop                    E.V.. use loop filter\n";
			text+="   gmc                     E.V.. use gmc\n";
			text+="   mv0                     E.V.. always try a mb with mv=<0,0>\n";
			text+="   part                    E.V.. use data partitioning\n";
			text+="   gray                    EDV.. only decode/encode grayscale\n";
			text+="   psnr                    E.V.. error[?] variables will be set during encoding\n";
			text+="   naq                     E.V.. normalize adaptive quantization\n";
			text+="   ildct                   E.V.. use interlaced dct\n";
			text+="   low_delay               EDV.. force low delay\n";
			text+="   alt                     E.V.. enable alternate scantable (mpeg2/mpeg4)\n";
			text+="   trell                   E.V.. use trellis quantization\n";
			text+="   bitexact                EDVAS use only bitexact stuff (except (i)dct)\n";
			text+="   aic                     E.V.. h263 advanced intra coding / mpeg4 ac prediction\n";
			text+="   umv                     E.V.. use unlimited motion vectors\n";
			text+="   cbp                     E.V.. use rate distortion optimization for cbp\n";
			text+="   qprd                    E.V.. use rate distortion optimization for qp selection\n";
			text+="   aiv                     E.V.. h263 alternative inter vlc\n";
			text+="   slice                   E.V..\n";
			text+="   ilme                    E.V.. interlaced motion estimation\n";
			text+="   scan_offset             E.V.. will reserve space for svcd scan offset user data\n";
			text+="   cgop                    E.V.. closed gop\n";

			flags.setToolTipText(text);
			
			/*
			 * do advanced
			 */
			Group group1=new Group(advancedComposite,SWT.NULL);
			group1.setLayout(new GridLayout(7,false));
			
			
	
	
			ParamCombo b_strategy= new ParamCombo(group1,SWT.NONE,"b_strategy","b_strategy",
					new String[]{"","0","1"});
			addParamList(b_strategy);
			
		
			/*
			ParamCombo max_b_frames= new ParamCombo(group1,SWT.NONE,"max_b_frames","max_b_frames",
					new String[]{"","0","1"});
			addParamList(max_b_frames);
			*/
			
			ParamCombo trellis= new ParamCombo(group1,SWT.NONE,"trellis","trellis",
					new String[]{"","0","1","2"});
			addParamList(trellis);
			
			ParamCombo refs= new ParamCombo(group1,SWT.NONE,"refs","refs",
					new String[]{"","0","1"});
			addParamList(refs);
			
			ParamCombo bf= new ParamCombo(group1,SWT.NONE,"bf","bf",
					new String[]{"","0","1","2","3","4","5"});
			addParamList(bf);
			
			
			
			ParamCombo coder= new ParamCombo(group1,SWT.NONE,"coder","coder",
					new String[]{"","0","1"});
			addParamList(coder);
			
			ParamCombo g= new ParamCombo(group1,SWT.NONE,"g","g",
					new String[]{"","12","18","32","50","100","200","250","300"});
			addParamList(g);
			
		
			
			ParamCombo deblockalpha= new ParamCombo(group1,SWT.NONE,"deblockalpha","deblockalpha",
					new String[]{"","0","1"});
			addParamList(deblockalpha);
			
			ParamCombo deblockbeta= new ParamCombo(group1,SWT.NONE,"deblockbeta","deblockbeta",
					new String[]{"","0","1"});
			addParamList(deblockbeta);
			
			ParamCombo mbd= new ParamCombo(group1,SWT.NONE,"mbd","mbd",
					new String[]{"","0","1","rd"});
			addParamList(mbd);
			
			ParamCombo chroma= new ParamCombo(group1,SWT.NONE,"chroma","chroma",
					new String[]{"","0","1"});
			addParamList(chroma);
			
			ParamCombo brdo= new ParamCombo(group1,SWT.NONE,"brdo","brdo",
					new String[]{"","0","1"});
			addParamList(brdo);
			
			
			
			ParamCombo slice= new ParamCombo(group1,SWT.NONE,"slice","slice",
					new String[]{"","0","1","2"});
			addParamList(slice);
			

			ParamCombo subq= new ParamCombo(group1,SWT.NONE,"subq","subq",
					new String[]{"","0","1","6"});
			addParamList(subq);
			
			
			ParamCombo sc_threshold= new ParamCombo(group1,SWT.NONE,"sc_threshold","sc_threshold",
					new String[]{"","0","1","40"});
			addParamList(sc_threshold);
			
			
			ParamCombo i_qfactor= new ParamCombo(group1,SWT.NONE,"i_qfactor","i_qfactor",
					new String[]{"","0","0.71","0.71428572"});
			addParamList(i_qfactor);
			ParamCombo qmin= new ParamCombo(group1,SWT.NONE,"qmin","qmin",
					new String[]{"","0","1","3","7","10","23"});
			addParamList(qmin);
			
			ParamCombo qmax= new ParamCombo(group1,SWT.NONE,"qmax","qmax",
					new String[]{"","1","5","25","35","40","51"});
			addParamList(qmax);
			
			ParamCombo qdiff= new ParamCombo(group1,SWT.NONE,"qdiff","qdiff",
					new String[]{"","0","1","2","3","4"});
			addParamList(qdiff);
			
			
			ParamCombo loop= new ParamCombo(group1,SWT.NONE,"loop","loop",
					new String[]{"","0","1"});
			addParamList(loop);
			
			ParamCombo qscale= new ParamCombo(group1,SWT.NONE,"qscale","qscale",
					new String[]{"","1","5"});
			addParamList(qscale);
			
			ParamCombo target= new ParamCombo(group1,SWT.NONE,"target","target",
					new String[]{"","ntsc-dvd","dvd","vcd","dv"});
			addParamList(target);
			
			ParamCombo profile= new ParamCombo(group1,SWT.NONE,"profile","profile",
					new String[]{"","aac_main","aac_low","aac_ssr","aac_ltp"});
			
			addParamList(profile);
			
		
			
			
			ParamCombo qcomp= new ParamCombo(group1,SWT.NONE,"qcomp","qcomp",
					new String[]{"","0","0.6"});
			addParamList(qcomp);
			
			ParamCombo keyint_min= new ParamCombo(group1,SWT.NONE,"keyint_min","keyint_min",
					new String[]{"","0","1","25"});
			addParamList(keyint_min);
			
			
			Group group2=new Group(advancedComposite,SWT.NULL);
			group2.setLayout(new GridLayout(6,false));
			
			ParamCombo cmp= new ParamCombo(group2,SWT.NONE,"cmp","cmp",
					new String[]{"","sad","sse","satd","dct","psnr","bit","rd","zero","vsad","vsse","sad","w53","w97","dctmax","chroma"});
			addParamList(cmp);
			
			ParamCombo subcmp= new ParamCombo(group2,SWT.NONE,"subcmp","subcmp",
					new String[]{"","sad","sse","satd","dct","psnr","bit","rd","zero","vsad","vsse","sad","w53","w97","dctmax","chroma"});
			addParamList(subcmp);
			
			ParamCombo rc_eq= new ParamCombo(group2,SWT.NONE,"rc_eq","rc_eq",
					new String[]{"","\"blurCplx^(1-qComp)\""});
			addParamList(rc_eq);
			
			ParamCombo me= new ParamCombo(group2,SWT.NONE,"me","me",
					new String[]{"","zero","full","log","phods","epzs","x1","hex","umh","iter"});
							
			addParamList(me);
			
			ParamCombo me_method= new ParamCombo(group2,SWT.NONE,"me_method","me_method",
					new String[]{"","0","1","8"});
			addParamList(me_method);
			
			
			ParamCombo me_range= new ParamCombo(group2,SWT.NONE,"me_range","me_range",
					new String[]{"","16","21"});
			addParamList(me_range);
			
			
			
			
			ParamCheckGroup partisions=new ParamCheckGroup(advancedComposite,SWT.NONE,"partitions","partitions",
					new String[]{"parti4x4","parti8x8","partp4x4","partp8x8","partb8x8"},5);
			partisions.setToolTipText("-partitions        <flags> E.V.. macroblock subpartition sizes to consider");
			addParamList(partisions);
			
			
			
			
			
			
			
			
			

			Composite advancedComposite2=new Composite(tab,SWT.NONE);
			advancedComposite2.setLayout(new GridLayout(1,true));
			CTabItem tabItem3 = new CTabItem(tab, SWT.NONE);
			tabItem3.setText("Advanced2");
			
			tabItem3.setControl(advancedComposite2);
			
			
			

			ParamCheckGroup flags2=new ParamCheckGroup(advancedComposite2,SWT.NONE,"flags2","flags2",
					new String[]{"fast","sgop","noout","local_header","bpyramid","wpred","mixed_refs","dct8x8","fastpskip","aud","brdo","skiprd",
					"ivlc","drop_frame_timecode","non_linear_q"},8);
			addParamList(flags2);
			String text2="";
			text2+="-flags2            <flags> EDVA.\n";
			text2+="   fast                    E.V.. allow non spec compliant speedup tricks\n";
			text2+="   sgop                    E.V.. strictly enforce gop size\n";
			text2+="   noout                   E.V.. skip bitstream encoding\n";
			text2+="   local_header            E.V.. place global headers at every keyframe instead of in extradata\n";
			text2+="   bpyramid                E.V.. allows B-frames to be used as references for predicting\n";
			text2+="   wpred                   E.V.. weighted biprediction for b-frames (H.264)\n";
			text2+="   mixed_refs              E.V.. one reference per partition, as opposed to one reference per macroblock\n";
			text2+="   dct8x8                  E.V.. high profile 8x8 transform (H.264)\n";
			text2+="   fastpskip               E.V.. fast pskip (H.264)\n";
			text2+="   aud                     E.V.. access unit delimiters (H.264)\n";
			text2+="   brdo                    E.V.. b-frame rate-distortion optimization\n";
			text2+="   skiprd                  E.V.. RD optimal MB level residual skipping\n";
			text2+="   ivlc                    E.V.. intra vlc table\n";
			text2+="   drop_frame_timecode         E.V..\n";
			text2+="   non_linear_q            E.V.. use non linear quantizer\n";
			flags2.setToolTipText(text2);
			
			
			
			
			
			Group group_time=new Group(advancedComposite2,SWT.NULL);
			group_time.setText("Time");
			group_time.setLayout(new GridLayout(7,false));
			
			ParamText ss= new ParamText(group_time,SWT.NONE,"ss","start");
			addParamList(ss);
			ParamText t= new ParamText(group_time,SWT.NONE,"t","duration");
			addParamList(t);
			
			Group group_crop=new Group(advancedComposite2,SWT.NULL);
			group_crop.setText("Crop");
			group_crop.setLayout(new GridLayout(7,false));
			
			ParamText croptop= new ParamText(group_crop,SWT.NONE,"croptop","croptop");
			addParamList(croptop);
			ParamText cropbottom= new ParamText(group_crop,SWT.NONE,"cropbottom","cropbottom");
			addParamList(cropbottom);
			ParamText cropleft= new ParamText(group_crop,SWT.NONE,"cropleft","cropleft");
			addParamList(cropleft);
			ParamText cropright= new ParamText(group_crop,SWT.NONE,"cropright","cropright");
			addParamList(cropright);
			
			
			Group group_pad=new Group(advancedComposite2,SWT.NULL);
			group_pad.setText("Padding");
			group_pad.setLayout(new GridLayout(7,false));
			
			ParamText padtop= new ParamText(group_pad,SWT.NONE,"padtop","padtop");
			addParamList(padtop);
			ParamText padbottom= new ParamText(group_pad,SWT.NONE,"padbottom","padbottom");
			addParamList(padbottom);
			ParamText padleft= new ParamText(group_pad,SWT.NONE,"padleft","padleft");
			addParamList(padleft);
			ParamText padright= new ParamText(group_pad,SWT.NONE,"padright","padright");
			addParamList(padright);
			
			ParamCombo padcolor= new ParamCombo(group_pad,SWT.NONE,"padcolor","padcolor",
					new String[]{"","000000","ffffff"});
			addParamList(padcolor);
			
			ParamCheckGroup debug=new ParamCheckGroup(advancedComposite2,SWT.NONE,"debug","debug",
					new String[]{"pict","rc","bitstream","qp","mv","dct_coeff","skip","startcode","pts","er","mmco","bugs","vis_qp","vis_mb_type"},8);
			addParamList(debug);
			
			
			/*
			 *    pict                    .DV.. picture info
   rc                      E.V.. rate control
   bitstream               .DV..
   mb_type                 .DV.. macroblock (MB) type
   qp                      .DV.. per-block quantization parameter (QP)
   mv                      .DV.. motion vector
   dct_coeff               .DV..
   skip                    .DV..
   startcode               .DV..
   pts                     .DV..
   er                      .DV.. error resilience
   mmco                    .DV.. memory management control operations (H.264)
   bugs                    .DV..
   vis_qp                  .DV.. visualize quantization parameter (QP), lower QP are tinted greener
   vis_mb_type             .DV.. visualize block types
			 */
			advancedComposite.setFocus();
			tab.setSelection(0);
			tab.forceFocus();//must for focus tab.
			updateStatus();
			
			
			Akj_betasPlugin.getDefault().getPluginPreferences().addPropertyChangeListener( new PreferenceStoreMonitor());
			
			//select item
			int defaultSelect=getPreferenceStore().getInt(H264SettingPage.EXPORT_H264_SETTINGS_INDEX);
			log.info("defaultSelect:"+defaultSelect);
			if(tableViewer.getTable().getItemCount()>defaultSelect){
				tableViewer.getTable().setSelection(Math.max(0,defaultSelect));//this method don't call SelectionChangedListener 
				
				}else{
					if(tableViewer.getTable().getItemCount()>0){
						tableViewer.getTable().setSelection(0);//this method don't call SelectionChangedListener 
					}else{
						log.info("item is empty");
					}
				}
			tableSelectionChanged();
			tableViewer.addSelectionChangedListener(new StoreSelect());
			
			return composite;
		}

		public class StoreSelect implements ISelectionChangedListener{

			public void selectionChanged(SelectionChangedEvent event) {
				getPreferenceStore().setValue(H264SettingPage.EXPORT_H264_SETTINGS_INDEX, tableViewer.getTable().getSelectionIndex());
			}
			
		}
		
		public void updateSettingTable(){
			List list=GenericParametersTableViewer.loadList(Akj_betasPlugin.getDefault().getPreferenceStore().getString(H264SettingPage.EXPORT_H264_SETTINGS));
			
			tableViewer.setGenericParametersList(list);
			
			
		
					if(tableViewer.getTable().getItemCount()>0){
						tableViewer.getTable().setSelection(0);//
						}
		}
		public class PreferenceStoreMonitor implements IPropertyChangeListener {

			public void propertyChange(PropertyChangeEvent event) {
				log.info(event.getProperty());
				if (event.getProperty().equals(H264SettingPage.EXPORT_H264_SETTINGS)) {
					updateSettingTable();
				}
			}

			

		}
		
public class SetPSPDir implements SelectionListener{

	public void widgetDefaultSelected(SelectionEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void widgetSelected(SelectionEvent e) {
		File roots[]=File.listRoots();
		for (int i = roots.length-1; i >0; i--) {
			File tmp=new File(roots[i],"PSP");
		if(tmp.exists()){
			File videoFolder=new File(roots[i],"VIDEO");
			if(videoFolder.exists()){
			directoryChooser.setEnabled(true);
			samefolder.setSelection(false);
			directoryChooser.setFile(videoFolder);
			updateStatus();
			}
			}
		}
		
	}
	
}



		
		
public class SavePreferenceStore implements SelectionListener{
			
			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				storeControl((Control)e.getSource());
			}
		}
		
		public void restoreControl(Control control){
			IPreferenceStore store=getPreferenceStore();
			
			if(control==avisynth){
				
				avisynth.setSelection(store.getBoolean(getPreferenceKey()+"."+AVISYNTH));
				
				}
			/*
			else if(control==twoPass){
					
					twoPass.setSelection(store.getBoolean(getPreferenceKey()+"."+TWO_PASS));
				
					}*/

			
		}
		
		public void selectCombo(CCombo combo,String value){
			int s=combo.getItemCount();
			for (int i = 0; i <s; i++) {
				if(combo.getItem(i).equals(value)){
					combo.select(i);
					break;
				}
			}
		}
		

		public void storeControl(Control control){
			IPreferenceStore store=getPreferenceStore();
			
			if(control==avisynth){
				
				
				store.setValue(getPreferenceKey()+"."+AVISYNTH, avisynth.getSelection());
				}/*else if(control==twoPass){
					
					
					store.setValue(getPreferenceKey()+"."+TWO_PASS, twoPass.getSelection());
					}*/
		}
		

		
		
		public String toTime(long bps,long maxMega){
			long bytes=bps/8;
			
			long second=maxMega*1024*1024/bytes;
			long hour=second/3600;
			second=second%3600;
			long min=second/60;
			long sec=second%60;
			
			String hstring=""+hour;
			if(hstring.length()<2){
				hstring="0"+hstring;
			}
			
			String mstring=""+min;
			if(mstring.length()<2){
				mstring="0"+mstring;
			}
			
			String sstring=""+sec;
			if(sstring.length()<2){
				sstring="0"+sstring;
			}
			return hstring+":"+mstring+":"+sstring;
		}

		public void inconvert(File file) {
			ffmpegExecuter.execute(new File[]{file});
		}

		
		public void beforeConvert() {
			ffmpegExecuter = new FFMpegExecuter();
			
			ffmpegExecuter.setExecuteListener(new FFMpegMonitor());
			
			
			//int select=tableViewer.getTable().getSelectionIndex();
			//log.infoselect:"+select);
			//GenericParameters setting=(GenericParameters) tableViewer.getGenericParameters().get(tableViewer.getTable().getSelectionIndex());
			Map newMap=toNewParameterMap();
			GenericParameters setting=new GenericParameters(newMap);
		
			
			
			//TODO convert
			
			GenericParametersFFMpegPreference preference=new GenericParametersFFMpegPreference(setting);
			
			
			String ffmpegPath = FFMpegUI.getFFmpeg();
			preference.setFfmpegPath(ffmpegPath);
			
			log.info(preference);
			
			//support thread.
			boolean threads = FFMpegUI.isUseThread();
			if(threads){
				if(FFMpegOptions.CODEC_VIDEO_H264.equals(preference.getVideoCodec()))
					preference.setThreads(2);//set thread only h264
			}
			
			ffmpegExecuter.setFfmpegPreference(preference);
			ffmpegExecuter.setUseAvisynth(avisynth.getSelection());
			ffmpegExecuter.setIgnoreAvisynthExtensions(new String[0]);//depend on
			
			
			ffmpegExecuter.setSameDirectory(samefolder.getSelection());
			ffmpegExecuter.setBackup(backup.getSelection());
			if(!samefolder.getSelection()){
				ffmpegExecuter.setExportDir(directoryChooser.getAbsoluteFilePath());
			}
			
		}
		


		public void afterConvert() {
			// TODO Auto-generated method stub
			
		}
		
		public class FFMpegMonitor implements DirectryBasedExecuterListener{

			public void beforeConvert() {
				// TODO Auto-generated method stub
				
			}

			public void afterConvert() {
				// TODO Auto-generated method stub
				setProgress(0);
			}

			public void startConvert(File file) {
				setProgress(0);
				
				//set guess size.
				FFMpegFLVParser parser=new FFMpegFLVParser(ffmpegExecuter.getFfmpegPreference().getFfmpegPath());
				FLVInfomation info=parser.parseFile(file);
				
				int guessSize=FFMpegPreference.toKBytes(info.getDuration(), ffmpegExecuter.getFfmpegPreference().getVideoBitrate()+ffmpegExecuter.getFfmpegPreference().getAudioBitrate());
				log.info("guessSize:"+guessSize);
				setProgressMaxBytes(guessSize*=1.1);//for fix to real situation
				//on avisynth how to work?
			}

			public void endConvert(File file) {
				setProgress(100);
				Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("[complete:h264]"+file.getAbsolutePath()+"\n\n");
				//make thumb
				String name=FileNameUtils.getChangedExtensionName(ffmpegExecuter.getCurrentOutputFile(), "jpg",true);
				File jpegFile=new File(name);
				ThumbnailManager.makeThumbnail(file, 3, jpegFile);
			}

			public void faildConvert(File file, String message) {
				Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("[faild:h264]"+message+","+file.getAbsolutePath()+"\n\n");
			}

			public void printProcess(String line) {
				//Akj_betasPlugin.getDefault().
				Akj_betasPlugin.getDefault().getProcessPrinter().printError(line);
				
				if(FFMpegUtils.isProgressString(line)){
					progressBytes(FFMpegUtils.getProgressSize(line));//progress bar work,call setProgress
				}
			}

			public boolean askOverwrite(File output) {
				
				return FileOverwriteControler.askOverwrite(fileOverwriteControler,output);
			}
			
		}
		//overwrite only work when ffmpeg is available
		public boolean isCanConvert(){
			
			String ffmpegPath = FFMpegUI.getFFmpeg();

			if (!FFMpegUtils.isFFMpegAvailable(ffmpegPath)) {
			return false;
			}
			return super.isCanConvert();
		}

		public void cancelConvert() {
			ffmpegExecuter.cancel();
		}

		public void updateStatus() {
			
			if(samefolder.getSelection() || directoryChooser.getFile()!=null){
				setMessage(Messages.getString("dropsomething.drag_folder"));
				setCanConvert(true);
			}else{
				setErrorMessage(Messages.getString("dropsomething.choose_folder"));
				setCanConvert(false);
			}
		}
		
		public void setMessage(String text){
			if(dragHere!=null){//before initialize
			dragHere.setForeground(new Color(null,64,255,64));
			dragHere.setText(text);
			}
		}
		public void setErrorMessage(String text){
			if(dragHere!=null){
			dragHere.setForeground(new Color(null,255,0,0));
			dragHere.setText(text);
			}
		}

		public IPreferenceStore getPreferenceStore(){
			return Akj_betasPlugin.getDefault().getPreferenceStore();
		}
		
		public boolean setFocus(){
			return tableViewer.getTable().setFocus();
			
		}
		
	}
	

	

	
	
}
